package com.heima.user.service.iml;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.exception.CustException;
import com.heima.common.exception.CustomException;
import com.heima.feigins.WemediaFigin;
import com.heima.feigins.ArticleFeigin;
import com.heima.model.article.pojos.ApAuthor;
import com.heima.model.common.constants.admin.AdminConstants;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dtos.AuthDTO;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.user.pojos.ApUserRealname;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.mapper.ApUserRealnameMapper;
import com.heima.user.service.ApUserRealnameService;

import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service("apUserRealnameService")
public class ApUserRealnameServiceImpl extends ServiceImpl<ApUserRealnameMapper, ApUserRealname> implements ApUserRealnameService {

    @Autowired
    ApUserMapper apUserMapper;

    @Autowired
    ArticleFeigin articleFeigin;

    @Autowired
    WemediaFigin wemediaFigin;

    @Override
    public ResponseResult<ApUserRealname> list(AuthDTO authDTO) {
        //参数校验
        if (authDTO == null){
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        authDTO.checkParam();
        //2 条件查询
        Page<ApUserRealname> page = new Page<>(authDTO.getPage(), authDTO.getSize());
        LambdaQueryWrapper<ApUserRealname> wrapper = new LambdaQueryWrapper<>();
        //状态是否又
        if (authDTO.getStatus() != null){
            wrapper.eq(ApUserRealname::getStatus,authDTO.getStatus());
        }
        IPage<ApUserRealname> iPage = this.page(page, wrapper);
        //3.返回结果
        return new PageResponseResult(authDTO.getPage(),authDTO.getSize(),iPage.getTotal(),iPage.getRecords());
    }

    @Override
   // @Transactional  普通事务，不能解决分布式事务
    @GlobalTransactional(timeoutMills = 100000,rollbackFor = Exception.class)  //解决分布式事务
    public ResponseResult<ApUserRealname> updateStatusById(AuthDTO authDTO, Short status) {
        //审核用户状态，审核不通过，后续不用做操作，审核通过，需要在自媒体库中创建一个新的账号，在文章库中创建一个作者文章账号
        //1.参数校验,id不能为空
          if (authDTO.getId() == null){
              CustException.cust(AppHttpCodeEnum.PARAM_INVALID,"id不能为空值");
          }
        //1.1根据id查询出用户实名认证的信息realname,并
        ApUserRealname apUserRealname = this.getById(authDTO.getId());
          if (apUserRealname == null){
              return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"实名用户信息不存在");
          }
           //实名认证是否待审核，不是待审核，或是审核过了就不用关了
        if (AdminConstants.WAIT_AUTH != apUserRealname.getStatus()){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_ALLOW,"该实名认证信息不是处于待审核状态");
        }
        //1.2 判断该认证用户是否有app端账号，根据ap_user_realname中关联的userId查询 ap_user
        ApUser apuser = apUserMapper.selectById(apUserRealname.getUserId());
          if (apuser == null){
              return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"实名认证用户关联app不存在");
          }
        // 2. 修改 ap_user_realname表status状态  9
            apUserRealname.setStatus(status);
          if (StringUtils.isNotBlank(authDTO.getMsg())){
              apUserRealname.setReason(authDTO.getMsg());
          }
        boolean b = this.updateById(apUserRealname);
          if (!b){
              return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"实名认证更改用户信息状态失败");
          }
        // 3 如果状态为9,为9开通两个库的账号信息
          if (AdminConstants.PASS_AUTH==status){
              //开通自媒体账号
              // 3.1  开通自媒体账户信息
              WmUser wmUser = createWemedia(apuser);
              // 3.2  创建作者信息
              createArticle(apuser,wmUser);
          }
        //System.out.println(1/0);
        return ResponseResult.okResult();
    }

    private void createArticle(ApUser apuser, WmUser wmUser) {
        ResponseResult<ApAuthor> byUserId = articleFeigin.findByUserId(apuser.getId());
        if(byUserId.getCode().intValue() != 0){ // 说明远程调用失败
            CustException.cust(AppHttpCodeEnum.REMOTE_SERVER_ERROR,byUserId.getErrorMessage());
        }
        ApAuthor apAuthor = byUserId.getData();
        if (apAuthor != null){
            CustException.cust(AppHttpCodeEnum.DATA_EXIST,"实名认证的用户已经有作者账号");
        }
        //创建账号
        apAuthor = new ApAuthor();
        apAuthor.setName(apuser.getName());
        apAuthor.setType(2); // 平台自媒体人
        apAuthor.setUserId(apuser.getId());
        apAuthor.setCreatedTime(new Date());
        apAuthor.setWmUserId(wmUser.getId());
        ResponseResult saveResult = articleFeigin.save(apAuthor);
        if(saveResult.getCode().intValue() != 0){ // 说明远程调用失败
            CustException.cust(AppHttpCodeEnum.REMOTE_SERVER_ERROR,byUserId.getErrorMessage());
        }
    }

    private WmUser createWemedia(ApUser apuser) {
        // 1. 根据用户名 查询 wmUser是否已经创建
        ResponseResult<WmUser> byName = wemediaFigin.findByName(apuser.getName());
        if(byName.getCode().intValue() != 0){ // 说明远程调用失败
            CustException.cust(AppHttpCodeEnum.REMOTE_SERVER_ERROR,byName.getErrorMessage());
        }
        WmUser wmUser = byName.getData();
        if (wmUser != null){
            CustException.cust(AppHttpCodeEnum.DATA_EXIST,"实名认证的用户已经有自媒体帐号了");
        }
        //创建账号
         wmUser = new WmUser();
        BeanUtils.copyProperties(apuser,wmUser);
        wmUser.setApUserId(apuser.getId()); // 关联的app账户id
        wmUser.setNickname(apuser.getName()); // 昵称
        wmUser.setStatus(9);
        wmUser.setType(0);
        wmUser.setCreatedTime(new Date());
        ResponseResult<WmUser> responseResult = wemediaFigin.save(wmUser);
        if(responseResult.getCode().intValue() != 0){ // 说明远程调用失败
            CustException.cust(AppHttpCodeEnum.REMOTE_SERVER_ERROR,byName.getErrorMessage());
        }
        return responseResult.getData(); // 返回保存成功的自媒体账户信息
    }


}
